#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

/**
 * 动态顺序表的操作
 */
using namespace std;

//数据类型定义
typedef char DateType;
#define InitSize 10 // 公共参数 初始化的大小
// 1、顺序表结构体
typedef struct sqList
{
    int length;  // 当前顺序表长度
    int Maxsize; // 顺序表最大长度
    DateType *data;  // 定义顺序表中元素类型的字符指针
} sqList;
// 输出数据
void printSqList(sqList *L)
{

    for (int i = 0; i < L->length; i++)
    {
        printf("位置：%d,元素：%c\n", i + 1, L->data[i]);
    }
}
// 初始化并赋值
void initSqList(sqList *L)
{
    // 强转指针+malloc 分配空间大小
    L->data = (char *)malloc(InitSize * sizeof(char));
    L->length = 0;
    L->Maxsize = InitSize;

    int n; // 顺序表大小
    printf("请输入顺序表大小：\n");
    scanf("%d", &n);
    L->length = n;
    char character;
    printf("请输入字符：\n");
    for (int i = 0; i < n; i++)
    {
        scanf(" %c", &character);
        L->data[i] = character;
    }
    printf("\n");
    printSqList(L);
}
// 扩展顺序表大小并销毁
void reInitSqList(sqList *L)
{
    int num = 0;
    scanf("%d", &num);
    char *p = L->data;
    L->data = (char *)malloc((InitSize + num) * sizeof(char));
    for (int i = 0; i < L->length; i++)
    {
        L->data[i] = p[i];
    }
    L->Maxsize += num;
    free(p);
}

// 顺序表按位查找
void getOne(sqList *L)
{

    int i;
    printf("请输入查找的位数：");
    scanf("%d", &i);
    if (i < 1 || i > L->length + 1)
    {
        printf("位数有误");
        return;
    }
    printf("顺序表第%d位为：%c", i, L->data[i - 1]);
}

// 顺序表 按值查找
void getOneByValue(sqList *L)
{
    char x;
    bool t = false;
    printf("请输入查找的值：");
    scanf("%s", &x);
    for (int i = 0; i < L->length; i++)
    {
        if (L->data[i] == x)
        {
            printf("顺序表第%d位为：%c", i + 1, L->data[i]);
            t = true;
        }
    }
    if (t = false)
    {
        printf("未找到");
    }
}
// 顺序表按位删除
void deleteValue(sqList *L)
{
    int i;
    printf("请输入想要删除的位数：\n");
    scanf("%d", &i);
    if (i < 1 || i > L->length)
    {
        printf("位数有误");
        return;
    }
    if (i <= L->length)
    {
        for (int j = i - 1; j < L->length; j++)
        {
            L->data[j] = L->data[j + 1];
        }
        L->length--;
    }
}
// 顺序表按位插入
void insertValue(sqList *L)
{
    int i;
    char e;
    printf("请输入想插入的元素和位置：");
    scanf(" %c %d", &e, &i);
    if (i < 1 || i > L->length)
    {
        printf("非法位置");
        return;
    }
    if (L->length == L->Maxsize)
    {
        printf("超过表长度");
        return;
    }
    if (i - 1 < L->length)
    {
        for (int j = L->length; j > i - 1; j--)
            L->data[j] = L->data[j - 1];
    }
    L->data[i - 1] = e;
    L->length++;
    printSqList(L);
}
int main()
{
    sqList L;
    char choice;
    char exit_choice;
    while (1)
    {
        printf("请选择您的操作：\n");
        printf("I. 初始化\n");
        printf("K. 扩容\n");
        printf("S. 按位查询\n");
        printf("V. 按值查询\n");
        printf("C. 按位插入\n");
        printf("D. 按位删除\n");
        printf("P. 输出\n");
        printf("E. 退出\n");

        scanf(" %c", &choice); // 加上空格忽略换行符

        switch (choice)
        {
        case 'I':
            printf("您选择了初始化操作。\n");
            initSqList(&L);
            break;
        case 'K':
            if (L.data == NULL)
            {
                printf("请先进行初始化操作！\n");
                break;
            }
            printf("您选择了扩容操作。\n");
            reInitSqList(&L);
            break;
        case 'S':
            if (L.data == NULL)
            {
                printf("请先进行初始化操作！\n");
                break;
            }
            printf("您选择了按位查询操作。\n");
            getOne(&L);
            break;
        case 'V':
            if (L.data == NULL)
            {
                printf("请先进行初始化操作!\n");
                break;
            }
            printf("您选择了按值查询操作。\n");
            getOneByValue(&L);
            break;
        case 'C':
            if (L.data == NULL)
            {
                printf("请先进行初始化操作!\n");
                break;
            }
            printf("您选择了按位插入操作\n");
            insertValue(&L);
            break;
        case 'P':
            if (L.data == NULL)
            {
                printf("请先进行初始化操作!\n");
                break;
            }
            printf("您选择了输出操作\n");
            printSqList(&L);
            break;
        case 'D':
            if (L.data == NULL)
            {
                printf("请先进行初始化操作!\n");
                break;
            }
            printf("你选择了按位删除操作\n");
            deleteValue(&L);
            break;
        case 'E':
            printf("您确定要退出吗？按E键确认退出，按其他键返回上级菜单。\n");
            scanf(" %c", &exit_choice); // 加上空格忽略换行符
            if (exit_choice == 'E' || exit_choice == 'e')
            {
                printf("谢谢使用，再见！\n");
                return 0;
            }
            break;
        default:
            printf("无效的选择，请重新选择。\n");
            break;
        }
    }
}